# 解释一下LEGB
# 变量名解析：LEGB原则
# LEGB作用域查找原则，当引用一个变量时，python按照以下顺序依次进行查找：
# 从本地变量中 -> Local（function）函数内部
# 在任意上层函数的作用域 -> Enclosing function locals 嵌套函数内部
# 在全局作用域 -> Global（module）
# 最后在内置作用域中查找 -> Built-in（python）
# 第一个能够完成查找的就算成功。变量在代码中被赋值的位置通常就决定了它的作用域。

# 什么是Document String（文档注释-文件级、函数级、类）
# Python有一个很奇妙的特性，称为 文档字符串 ，它通常被简称为 docstrings 。
# DocStrings是一个重要的工具，由于它帮助你的程序文档更加简单易懂，
# 你应该尽量使用它。你甚至可以在程序运行的时候，从函数恢复文档字符串！
# 使用DocStrings

# unpack的用途 （ li = (1, 2, 3); a,b = *li）
# Python中按一定的格式取出某字符串中的子字符串，使用struck.unpack是非常高效的。
# pack可视为将一系列的片段的数值打包在一起，可用於对 dev档案、socket、memory
# 的读写，因为这些需要一块完整的memory，而且需要事先打包成特定格式；
# 而unpack可以视为将将这些完整 的memory切割计算，取得我们所需要各部分的Variable。

# global关键字的用途
# python中global关键字主要作用是声明变量的作用域。
# 在python中，变量不需要先声明，直接使用即可，那我们怎么知道用的是局部变量还是全局变量呢？
# 首先：python使用的变量，在默认情况下一定是用局部变量。
# 其次：python如果想使用作用域之外的全局变量，则需要加global前缀。

# locals函数的用途
# locals() 函数会以字典类型返回当前位置的全部局部变量。
# 对于函数, 方法, lambda 函式, 类,
# 以及实现了 __call__ 方法的类实例, 它都返回 True。
def runoob(arg):    # 两个局部变量：arg、z
    z = 1
    print (locals())

runoob(4)
{'z': 1, 'arg': 4}      # 返回一个名字/值对的字典

# 案例
def test():
    name = 'xiaodeng'
    version = 2.7
    time = '2015.11.07'
    print
    locals()


print
test()  # {'version': 2.7, 'name': 'xiaodeng', 'time': '2015.11.07'}

# 必选(位置)参数
#       用户输入2个数
#       比较两个数大小
#       可以比较N次，输入Q结束
#       定义函数实现
while True:
    first_num = int(input("第一个数：(输入q退出)"))
    if first_num == 'q':
        break
    else:
        sec_num = int(input("第二个数：(输入q退出)"))
        if sec_num == 'q':
            break
        else:
            if first_num > sec_num :
                print("第一个数{}大于第二个数{}".format(first_num,sec_num))
            else:
                print("第二个数{}大于第一个数{}".format(sec_num,first_num))
#       定义函数实现
def compare(first_num,sec_num):
    if first_num > sec_num:
        print("第一个数{}大于第二个数{}".format(first_num, sec_num))
    else:
        print("第二个数{}大于第一个数{}".format(sec_num, first_num))

while True:
    first_num = int(input("第一个数：(输入q退出)"))
    if first_num == 'q':
        break
    else:
        sec_num = int(input("第二个数：(输入q退出)"))
        if sec_num == 'q':
            break
        else:
            compare(first_num, sec_num)

# 默认参数
#       用户输入字符串和重复次数
#       输出str*times(使str重复输出times次)
#       用户输入不合法，给予提示
#       默认输出3次
#       定义函数实现
str = input("输入字符串：")
if str[0] == '\'' and str[-1] == '\'' or str[0] == '\"' and str[-1] == '\"' :
    times = int(input("输入重复次数："))
    for i in range(1,times+1):
        print(str)
else:
    print("输入不合法，请输入字符串。")


    #       定义函数实现
    def str_times(str, times):
        if str[0] == '\'' and str[-1] == '\'' or str[0] == '\"' and str[-1] == '\"':

            for i in range(1, times + 1):
                print(str)
        else:
            print("输入不合法，请输入字符串。")


    str = input("输入字符串：")
    times = int(input("输入重复次数："))
    str_times(str, times)

    # 变长参数
#       计算N个数的和
#       定义函数实现
#       用户输入，输入以Q结束
#       用户输入不合法，给予提示
sum = 0
while True:
    num = input("请输入数字：（输入Q结束）")
    if num == 'Q' :
        print("和为{}".format(sum))
        break
    else:
        if num.isdigit():
            sum += int(num)
        else:
            print("输入不合法，请输入数字")

#       定义函数实现
            def num_sum():
                while True:
                    global sum
                    num = input("请输入数字：（输入Q结束）")
                    if num == 'Q':
                        print("和为{}".format(sum))
                        break
                    else:
                        if num.isdigit():
                            sum += int(num)
                        else:
                            print("输入不合法，请输入数字")


            sum = 0
            num_sum()

# 匿名函数实现
#       计算三角形的面积 = > 用匿名函数实现 (lambda a : a*2 )(5)
#       给普通函数添加文档注释(document string)
from cmath import sqrt
a = int(input("输入边长a："))
b = int(input("输入边长b："))
c = int(input("输入边长c："))
p = lambda  a,b,c : (a+b+c) / 2
p = int(p(a,b,c))
#转换p为整形
s = lambda  p,a,b,c : sqrt(p*(p-a)*(p-b)*(p-c))
s = s(p,a,b,c)
#s结果为复数形式
s =complex(s).real
#取实部
print("面积为：{}".format(s))

# 递归函数
#       用递归实现fab
#       编写好文档注释
#       命令行实现
#       计算N个数的和

lists = []
while   True:
    n = input("输入数字：")
    if n == 'q':
        break
    else:
        lists.append(int(n))

#构建 递归求和函数
def sum(lists):
    if lists==[]:
        return 0
    return lists[0]+sum(lists[1:]) #每次调用取列表的第一个值
print(sum(lists))